#pragma once 

#include "HeightMap.h" 
#include "CreateHill.h"
#include "GenerateHeightMap.h"
#include "GenerateSurface.h"
#include "GroundTypes.h"

#include "IRenderable.h"
#include "ICustomModelRenderable.h"
#include "GeometryUtils.h"
#include <memory>

class Water;
class Landscape;

class Ground
  { 
  public:
    HSMODEL_API Ground(HeightMap i_height_map, double i_cell_size, double i_watel_level);
    HSMODEL_API virtual ~Ground();
    HSMODEL_API void CreateHighland(TVector2 i_point, double i_height_change);
    HSMODEL_API void CreateHole(TVector2 i_point, double i_height_change);
    HSMODEL_API void CreateWalkway(TVector2 i_point);

    HSMODEL_API void AddWaterModel(std::shared_ptr<Water> ip_water);
    HSMODEL_API void SetGrass(TVector2 i_point);

    HSMODEL_API void RemoveWaterModel(size_t i_model_index);

    HSMODEL_API EGroundType GetGroundType(size_t i_hmap_coord_x, size_t i_hmap_coord_y) const;
    HSMODEL_API const TGroundTypeMap& GetGroundTypeMap() const;

    HSMODEL_API const Landscape& GetLandscape() const;
    HSMODEL_API std::vector<ICustomModelRenderable*> GetObjectsToRender() const;
    HSMODEL_API const std::vector<std::shared_ptr<Water>>& GetWaterModels() const;

    HSMODEL_API void SetGroundType(size_t i_x, size_t i_y, EGroundType i_type); 
    HSMODEL_API void ResetGroundTypes(const TGroundTypeMap &i_map);
		HSMODEL_API EGroundType GetGroundType(const TVector2& i_point) const;
		HSMODEL_API std::pair<size_t, size_t> GetCellPosition(const TVector2& i_point) const;
    HSMODEL_API double GetHeightForXY(TVector2 i_point) const;

    HSMODEL_API HeightMap& GetHeightMap();
		HSMODEL_API const HeightMap& GetHeightMap() const;
  private:
 		std::pair<size_t, size_t> _FindHeightMapIndexes(const TVector2& i_point) const;   
		HSMODEL_API void _UpdateSurface();
    HSMODEL_API void _CreateGround();

  private:
    HeightMap m_height_map;
    std::shared_ptr<Landscape> m_landscape;
    std::vector<std::shared_ptr<Water>> m_water_models;
    double m_cell_size_in_height_map;
    TGroundTypeMap m_ground_types;
    double m_water_level;
  };